package com.chuangjiangx.member.manager.basic.web.interceptor;

import com.chuangjiangx.commons.JacksonUtils;
import com.chuangjiangx.member.manager.basic.web.controller.BaseController;
import com.chuangjiangx.member.manager.basic.web.response.Response;
import com.chuangjiangx.member.manager.common.Constants;
import com.chuangjiangx.privileges.olddao.dto.MerchantComponentCommon;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * 权限拦截
 */
@Slf4j
public class PermissionsInterceptor  extends HandlerInterceptorAdapter {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (handler instanceof HandlerMethod) {
            HandlerMethod method = (HandlerMethod) handler;
            Permissions permissions = method.getMethodAnnotation(Permissions.class);
            if (permissions != null) {
                String token = request.getHeader(Constants.TOKEN_STR);
                if(!StringUtils.isEmpty(token)){
                    clientPermission(request,response,token,permissions,method);
                }else{
                    webPermission(request,response,permissions,method);
                }
            }
        }
        return true;
    }


    /**
     * 商户APP接口访问权限验证
     * @return
     */
    private boolean clientPermission(HttpServletRequest request, HttpServletResponse response,String token,Permissions permissions,HandlerMethod method) throws  Exception{

        String json = (String) redisTemplate.opsForValue().get((Constants.COMPONENLIST + token));
        if(StringUtils.isBlank(json)){
            return resWriter(response);
        }
        CollectionType collectionType = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, MerchantComponentCommon.class);
        List<MerchantComponentCommon> components = objectMapper.readValue(json, collectionType);
        if (components == null || components.size() == 0) {
            return resWriter(response);
        }

        //方法的权限编码
        String code = permissions.value();
        for (MerchantComponentCommon next : components) {
            //有权限访问
            if (next.getCode().equals(code)) {
                return true;
            }
        }
//        MerchantUserCommon common = (MerchantUserCommon) request.getSession()
//                .getAttribute(BaseController.SESSION_USER);
//        if (common != null) {
//            log.warn("用户ID:{}不具备{}.{}功能的访问权限",common.getId(),method.getBeanType()
//                    .getSimpleName(),method.getMethod().getName() );
//        }
        //迭代后没有权限访问
        return resWriter(response);
    }

    /**
     * 商户WEB接口访问权限验证
     * @return
     */
    private boolean webPermission(HttpServletRequest request, HttpServletResponse response,Permissions permissions,HandlerMethod method) throws  Exception{
        /**
         * 由于是session共享,存储时对象类型是权限模块的 MerchantComponentCommon 而序列化是 JdkSerializationRedisSerializer
         */
        List<MerchantComponentCommon> components = (List<MerchantComponentCommon>) request.getSession().getAttribute(BaseController.SESSION_USER_COMPONENTS);
        //没有权限
        if (components == null ) {
            return resWriter(response);
        }

        String code = permissions.value();
        for (MerchantComponentCommon next : components) {
            //有权限访问
            if (next.getCode().equals(code)) {
                return true;
            }
        }
//        MerchantUserCommon common = (MerchantUserCommon) request.getSession().getAttribute(BaseController.SESSION_USER);
//        log.warn("用户ID:{}不具备{}.{}功能的访问权限",common.getId(),method.getBeanType().getSimpleName(),method.getMethod().getName());
        //迭代后没有权限访问
        return resWriter(response);
    }

    /**
     * 权限错误统一返回
     * @param response
     * @return
     * @throws Exception
     */
    private boolean resWriter(HttpServletResponse response) throws Exception {
        response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
        response.setContentType(ContentType.APPLICATION_JSON.getMimeType());
        Response resp = new Response(false);
        resp.setErr_code("000002 ");
        resp.setErr_msg("无权限使用该功能");
        response.getWriter().println(JacksonUtils.toJson(objectMapper,resp));
        return false;
    }

}
